<html>
<head>
<title>CpcPaChi - Version 0.17</title>
<style type="text/css">
span {
	font-family: 'Courier New';
	font-size: 10pt;
	color: #000000;
}
.sc0 {
	color: #808080;
}
.sc3 {
	color: #008080;
}
.sc4 {
	color: #FF8000;
}
.sc5 {
	font-weight: bold;
	color: #0000FF;
}
.sc7 {
	color: #808080;
}
.sc9 {
	color: #804000;
}
.sc10 {
	font-weight: bold;
	color: #000080;
}
.sc11 {
}
</style>
</head>
<body>
<h2>Un compilador sencillo paso a paso (17 - Alguna funci&oacute;n predefinida)</h2>

<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>

<p>Hasta ahora pod&iacute;amos hacer asignaciones sencillas, como a := 2, pero en el mundo real hay mucho m&aacute;s que eso: podemos encontrarnos con operaciones en una asignaci&oacute;n,como posicion := columna * 40 + fila, o con valores obtenidos de funciones, como en tecla := readkey.</p>

<p>Las expresiones matem&aacute;ticas las trataremos en el siguiente acercamiento. Ahora vamos a a&ntilde;adir alguna funci&oacute;n predefinida, como el anterior &quot;readkey&quot;, que nos permita ver qu&eacute; tecla ha pulsado el usuario.</p>

<p>Antes hac&iacute;amos asignaciones a variables a partir de valores que eran constantes num&eacute;ricas o constantes con nombre, de modo que se pod&iacute;a solucionar apenas en dos pasos:</p>

<pre><code>LD A, valor
LD (variable), A</code></pre>

<p>Ahora el primer paso cambiar&amp;aacute; ligeramente: guardar&amp;aacute; el valor en el registro A, pero este valor puede provenir de diversos sitios: ser&aacute; &quot;LD A, (variable)&quot; si viene de una variable, o pasaremos el testigo a la funci&oacute;n si corresponde. Muchas de las funciones predefinidas para el CPC devuelven su resultado en el registro A, como CALL &amp;BB18, que espera a que se pulse una tecla; otras devuelven el resultado en otros registros, como HL; y tendremos que extraer lo que nos interese con &oacute;rdenes como &quot;LD A, H&quot;; otras activan flags como C o Z, y entonces tendremos que usar estructuras de control como RET Z: nos podr&iacute;a interesar emplear secuencias como &quot;LD A, 1 - RET NZ - LD A, 0 - RET&quot;</p>

<p><br />Vamos a aprovechar para hacer otra mejora: los programas que genera nuestro compilador tienen un tama&ntilde;o relativamente grande, si tenemos en cuenta que la arquitectura de destino es un ordenador que deja libre poco m&aacute;s 40 Kb para programas de usuario. Parte de ese tama&ntilde;o (cerca de la mitad) se debe a la cantidad de comentarios que se incluyen en el c&oacute;digo generado. Estos comentarios son &uacute;tiles a la hora de depurar fallos de generaci&oacute;n de c&oacute;digo, pero deber&iacute;an ser innecesarios (o casi) cuando el compilador est&eacute; terminado. Por eso, es razonable a&ntilde;adir la posibilidad de eliminar los comentarios en el c&oacute;digo de destino. Para eso, cambiaremos la forma de generar c&oacute;digo. Antes se usaban cosas &quot;muy artesanales&quot; como:</p>

<pre><code>  writeln( ficheroDestino, lineaActual,' DATA CD,5A,BB: '' CALL &BB5A - WRITECHAR' );
  lineaActual := lineaActual + 10;
  longitudTotal := longitudTotal + 3;
</code></pre>

<p>El c&oacute;digo alternativo actual podr&iacute;a ser una funci&oacute;n &quot;genCodigo&quot; (generar codigo), que permita crear una orden DATA con una secuencia de hasta 3 bytes, que es lo m&aacute;s habitual en nuestra arquitectura de destino. Por si alguna orden es m&aacute;s corta, el primer par&aacute;metro ser&aacute; la longitud real (si es menor que tres, se despreciar&iacute;a el valor de alguno de los par&aacute;metros). El &uacute;ltimo par&aacute;metro ser&aacute; el comentario, de forma que se pueda omitir con facilidad:</p>

<pre><code>genCodigo(3, 'CD', '5A', 'BB', 'CALL &BB5A - WRITECHAR' );</code></pre>

<p><br />De paso, vamos a a&ntilde;adir alguna posibilidad mas, como que WriteChar permita usar variables, no s&oacute;lo textos prefijados, aprovechando la misma rutina de lectura de valores que hemos utilizado en las asignaciones. Ahora ser&aacute;n v&aacute;lidas tambi&eacute;n expresiones como </p>

<pre><code>writeChar(letra);</code></pre>

<p>(aunque como s&oacute;lo tenemos un tipo de variables, byte, esa variable &quot;letra&quot; deber&iacute;a ser de tipo &quot;byte&quot;, todav&iacute;a no de tipo &quot;char&quot;, que es lo que ser&iacute;a m&aacute;s razonable). </p>

<p>Con estos cambios ya se podr&aacute;n hacer secuencias de &oacute;rdenes como:</p>

<pre><code>  writeString('Pulsa una tecla: ');
  tecla := readkey;
  writeString('Has pulsado: ');
  writeChar(tecla);</code></pre>


<p><br />
  Como siempre, para m&aacute;s detalles, todo el c&oacute;digo est&aacute; en la p&aacute;gina del proyecto en Google Code:<br />
  <br />
  <a href="http://code.google.com/p/cpcpachi/">http://code.google.com/p/cpcpachi/</a></p>
<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>
</body>
</html>
